package pira.elements;


import java.io.PrintStream;

import org.neo4j.graphdb.Node;

import pira.db.ui.GraphDBUI;
import pira.db.ui.SubDBUI;

public class Author extends Neo4jNode {
	private String firstName;
	private String middleName;
	private String lastName;
	private String fullName;
	private String normalName;
	
	private String authorID;
	
	public String getAuthorID() {
		return authorID;
	}

	public void setAuthorID(String authorID) {
		this.authorID = authorID;
	}

	// constant for node properties
	public static final String FIRSTNAME = "first name";
	public static final String MIDDLENAME = "middle name";
	public static final String LASTNAME = "last name";
	public static final String FULLNAME = "full name";
	
	
	public static final String PUBLICATIONNUMBER = "publication number";
	public static final String HINDEX = "h index";
	
	public static final String PUBLICATIONORDER = "rank of publication";
	public static final String HINDEXORDER = "rank of h-index";
	
	// constant for authors index
	public static final String ORDER = "order";
	public static final String NAME = "name";
	public static final String AUTHORID = "author id";
	public static final String PAPER = "paper";
	
	public Author() {}
	
	public Author(Node node) {
		this.firstName= (String) node.getProperty(FIRSTNAME);
		this.middleName= (String) node.getProperty(MIDDLENAME);
		this.lastName= (String) node.getProperty(LASTNAME);
		this.fullName = (String) node.getProperty(FULLNAME);
		this.normalName = SubDBUI.normal(fullName);
	}

	public Author(String fullName) {
		this.fullName= fullName;
		String[] str= fullName.split(" ");
		int len= str.length;
		if (len == 3) {
			this.firstName= str[0].trim();
			this.middleName= str[1].trim();
			this.lastName= str[2].trim();
		} else if (len == 2) {
			this.firstName= str[0].trim();
			this.middleName= GraphDBUI.NOT_EXIST;
			this.lastName= str[1].trim();
		} else if (len == 1) {
			this.firstName= GraphDBUI.NOT_EXIST;
			this.middleName= GraphDBUI.NOT_EXIST;
			this.lastName= fullName.trim();
		} else if (len > 3) {
			this.firstName= str[0].trim();
			this.middleName= "";
			for (int i= 1; i < len-1; i++)
				this.middleName+= str[i].trim() + " ";
			this.middleName = this.middleName.trim();
			this.lastName= str[len-1].trim();
		}
		this.normalName = SubDBUI.normal(this.fullName);
	}
	
	public void getFromNode(Node node) {
		this.firstName= (String) node.getProperty(FIRSTNAME);
		this.middleName= (String) node.getProperty(MIDDLENAME);
		this.lastName= (String) node.getProperty(LASTNAME);
		this.fullName = (String) node.getProperty(FULLNAME);
		this.normalName = SubDBUI.normal(fullName);
	}
	
	public void setName(String fullName) {
		this.fullName= fullName;
		String[] str= fullName.split(" ");
		int len= str.length;
		if (len == 3) {
			this.firstName= str[0].trim();
			this.middleName= str[1].trim();
			this.lastName= str[2].trim();
		} else if (len == 2) {
			this.firstName= str[0].trim();
			this.middleName= GraphDBUI.NOT_EXIST;
			this.lastName= str[1].trim();
		} else if (len == 1) {
			this.firstName= GraphDBUI.NOT_EXIST;
			this.middleName= GraphDBUI.NOT_EXIST;
			this.lastName= fullName.trim();
		} else if (len > 3) {
			this.firstName= str[0].trim();
			this.middleName= "";
			for (int i= 1; i < len-1; i++)
				this.middleName+= str[i].trim() + " ";
			this.middleName = this.middleName.trim();
			this.lastName= str[len-1].trim();
		}
		if (this.middleName.equals(""))
			this.middleName = GraphDBUI.NOT_EXIST;
		if (this.firstName.equals(""))
			this.firstName = GraphDBUI.NOT_EXIST;
		if (this.lastName.equals(""))
			this.lastName = GraphDBUI.NOT_EXIST;
		
		this.normalName = SubDBUI.normal(this.fullName);
	}

	@Override
	public String toString() {
		return fullName;
	}
	
	// judge weather two authors are the same one
	public boolean equals(Author other) {
		this.toLowerCase();
		other.toLowerCase();
		if (!this.lastName.equals(other.lastName))
			return false;
		
		if (!this.middleName.equals(GraphDBUI.NOT_EXIST) &&
			!other.middleName.equals(GraphDBUI.NOT_EXIST)) {
			if (!this.isSameName(this.middleName, other.middleName))
				return false;
		}
			
		if (!this.firstName.equals(GraphDBUI.NOT_EXIST) &&
			!other.firstName.equals(GraphDBUI.NOT_EXIST)) {
			if (!this.isSameName(this.firstName, other.firstName))
				return false;
		}
		return true;
	}
	
	// judge whether two names are same
	private boolean isSameName(String name1, String name2) {
//System.out.println("name1 : " + name1);
//System.out.println("name2 : " + name2);
		if (name1.equals(name2)) 
			return true;
		else {
			if ((name1.length() == 2 && name1.charAt(1) == '.') || name1.length() == 1) {
				if (name1.charAt(0) == name2.charAt(0)) 
					return true;
				else 
					return false;
			} else if ((name2.length() == 2 && name2.charAt(1) == '.') || name2.length() == 1) {
				if (name1.charAt(0) == name2.charAt(0))
					return true;
				else 
					return false;
			} else 
				return false;
		}
	}
	
	private void toLowerCase() {
		if (!firstName.equals(GraphDBUI.NOT_EXIST))
			firstName = firstName.toLowerCase();
		if (!middleName.equals(GraphDBUI.NOT_EXIST))
			middleName = middleName.toLowerCase();
		if (!lastName.equals(GraphDBUI.NOT_EXIST))
			lastName = lastName.toLowerCase();
		fullName = fullName.toLowerCase();
	}
	
	public void print(PrintStream out) {
		out.println("Author");
		out.println("  First Name -> " + firstName);
		out.println("  Middle Name -> " + middleName);
		out.println("  Last Name -> " + lastName);
		out.println("  Full Name -> " + fullName);
		out.println("  Normal Name -> " + normalName);
	}

	// this requires that both of their first name exist
	public boolean equals2(Author other) {
		this.toLowerCase();
		other.toLowerCase();
		if (!this.lastName.equals(other.lastName))
			return false;
		
		if (this.firstName.equals(GraphDBUI.NOT_EXIST) ||
			other.firstName.equals(GraphDBUI.NOT_EXIST))
			return false;
		
		if (!this.middleName.equals(GraphDBUI.NOT_EXIST) &&
			!other.middleName.equals(GraphDBUI.NOT_EXIST) &&
			!this.middleName.equals("") && !other.middleName.equals("")) {
			if (!this.isSameName(this.middleName, other.middleName))
				return false;
		}
			
		if (!this.firstName.equals(GraphDBUI.NOT_EXIST) &&
			!other.firstName.equals(GraphDBUI.NOT_EXIST)) {
			if (!this.isSameName(this.firstName, other.firstName))
				return false;
		}
		return true;
	}
	
	public String getFirstName() {
		return firstName;
	}

	public String getMiddleName() {
		return middleName;
	}

	public String getLastName() {
		return lastName;
	}

	public String getFullName() {
		return fullName;
	}

	public void setFullName(String fullName) {
		this.fullName = fullName;
	}
	
	public String getNormalName() {
		return normalName;
	}

}
